package com.wy.config.authorization;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.ObjectUtils;

import dream.flying.flower.framework.security.constant.ConstSecurity;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * 重定向至登录处理
 * 
 * @author 飞花梦影
 * @date 2024-09-18 22:15:58
 * @git {@link https://github.com/dreamFlyingFlower}
 */
@Slf4j
public class LoginTargetAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

	private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

	/**
	 * @param loginFormUrl URL where the login page can be found. Should either be
	 *        relative to the web-app context path (include a leading {@code /}) or
	 *        an absolute URL.
	 */
	public LoginTargetAuthenticationEntryPoint(String loginFormUrl) {
		super(loginFormUrl);
	}

	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException, ServletException {

		// 获取登录表单的地址
		String loginForm = determineUrlToUseForThisRequest(request, response, authException);
		if (!UrlUtils.isAbsoluteUrl(loginForm)) {
			// 不是绝对路径调用父类方法处理
			super.commence(request, response, authException);
			return;
		}

		StringBuffer requestUrl = request.getRequestURL();
		if (!ObjectUtils.isEmpty(request.getQueryString())) {
			requestUrl.append("?").append(request.getQueryString());
		}

		// 2023-07-11添加逻辑：重定向地址添加nonce参数，该参数的值为sessionId
		// 绝对路径在重定向前添加target参数
		String targetParameter = URLEncoder.encode(requestUrl.toString(), StandardCharsets.UTF_8);
		String targetUrl = loginForm + "?target=" + targetParameter + "&" + ConstSecurity.NONCE_HEADER_NAME + "="
				+ request.getSession(Boolean.FALSE).getId();
		log.debug("重定向至前后端分离的登录页面：{}", targetUrl);
		this.redirectStrategy.sendRedirect(request, response, targetUrl);
	}
}